package com.daguchuangyi.erp_android.productlist.productsummary;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.daguchuangyi.erp_android.R;
import com.daguchuangyi.erp_android.manager.NetworkManager;
import com.daguchuangyi.erp_android.manager.ParameterManager;
import com.daguchuangyi.erp_android.manager.networkservice.ProductService;
import com.daguchuangyi.erp_android.manager.networkservice.model.ParamRequestModel;
import com.daguchuangyi.erp_android.model.LocalMediaWrapper;
import com.daguchuangyi.erp_android.model.product.Product;
import com.daguchuangyi.erp_android.productlist.ProductSummaryManager;
import com.daguchuangyi.erp_android.productlist.classifiaction.ClassificationManager;
import com.daguchuangyi.erp_android.productlist.imagetell.widget.ImageTellProgressDialog;
import com.daguchuangyi.erp_android.productlist.productsummary.widge.ImageTellHeader;
import com.daguchuangyi.erp_android.productlist.productsummary.widge.SummaryDecoration;
import com.daguchuangyi.erp_android.productlist.widget.TempFloatView;
import com.daguchuangyi.erp_android.util.ErrorHandler;
import com.jude.utils.JUtils;
import com.kaopiz.kprogresshud.KProgressHUD;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
import rx.subscriptions.CompositeSubscription;

public class ProductSummaryFragment extends Fragment implements
        ProductSummaryManager.OnProductCheckChangeListenner,
        ParameterManager.OnParamsChangeListener {
    private static final String TAG = ProductSummaryFragment.class.getSimpleName();

    private static final int PAGE_SIZE = 10;

    private int mNextRequestPage = 1;

    private RecyclerView mProductRv;
    private ProductSummaryAdapter mSummaryAdapter;

    private View mEmptyView;

    private CompositeSubscription mCompositeSubscription = new CompositeSubscription();

    private TempFloatView mTempFloatView;
    private SummaryDecoration mSummaryDecoration;

    public ProductSummaryFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_product_summary, container, false);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mProductRv = view.findViewById(R.id.product_rv);
        mSummaryAdapter = new ProductSummaryAdapter(null);
        mSummaryAdapter.setEnableLoadMore(true);
        mSummaryAdapter.setOnLoadMoreListener(this::loadMoreData, mProductRv);
        mSummaryAdapter.disableLoadMoreIfNotFullPage();

        mEmptyView = view.findViewById(R.id.empty_view);
        mTempFloatView = view.findViewById(R.id.temp_float_view);

        mSummaryDecoration = new SummaryDecoration(JUtils.dip2px(18), JUtils.dip2px(12), JUtils.dip2px(22));

        refreshStyleState();
        JUtils.Log(TAG, "onViewCreated");
        refreshData(false, true);

        ProductSummaryManager.getInstance().addProductCheckChangeListener(this);
        ParameterManager.getInstance().addOnParamsChangeListener(this);
    }

    public void refreshStyleState() {
        JUtils.Log(TAG, "refresh style was called.");
        mProductRv.removeItemDecoration(mSummaryDecoration);
        int currentStyle = ProductSummaryManager.getInstance().getCurrentState();


        if (currentStyle == ProductSummaryManager.STYLE_GRID) {
            int lastPostion = 0;
            RecyclerView.LayoutManager layoutManager = mProductRv.getLayoutManager();
            if (layoutManager != null && layoutManager instanceof LinearLayoutManager) {
                lastPostion = ((LinearLayoutManager)mProductRv.getLayoutManager()).findFirstVisibleItemPosition();
            }

            mProductRv.setLayoutManager(new GridLayoutManager(getContext(), 2));
            mProductRv.setAdapter(mSummaryAdapter);
            mProductRv.addItemDecoration(mSummaryDecoration);
            mProductRv.scrollToPosition(lastPostion);
//            int dp12 = JUtils.dip2px(12);
//            mProductRv.setPadding(dp12, 0, dp12, 0);
        } else if (currentStyle == ProductSummaryManager.STYLE_LIST) {
            RecyclerView.LayoutManager layoutManager = mProductRv.getLayoutManager();
            int lastPostion = 0;
            if (layoutManager != null && layoutManager instanceof GridLayoutManager) {
                lastPostion = ((GridLayoutManager)mProductRv.getLayoutManager()).findFirstVisibleItemPosition();
            }
            mProductRv.setLayoutManager(new LinearLayoutManager(getContext()));
            mProductRv.setAdapter(mSummaryAdapter);
            mProductRv.scrollToPosition(lastPostion);
//            mProductRv.setPadding(0, 0, 0, 0);
        }
    }

    public void refreshData(boolean showHud) {
        refreshData(showHud, true);
    }

    public void refreshData(boolean showHud, boolean fullyRefresh) {
        JUtils.Log(TAG, "refresh data was called.");
        mNextRequestPage = 1;
//        mSummaryAdapter.removeAllHeaderView();
        loadDataFromServer(mNextRequestPage, true, showHud, fullyRefresh);
    }


    private void loadDataFromServer(int page, boolean isRefresh, boolean showHud, boolean fullyRefresh) {
        JUtils.Log("load data from server called. page is : " + page);
        showHud &= !TextUtils.equals(ClassificationManager.getInstance().getExtralMode(), ClassificationManager.MODE_EXTRA_KEY_LIKE);

        final KProgressHUD hubDialog = showHud ? KProgressHUD.create(getContext())
                .setStyle(KProgressHUD.Style.SPIN_INDETERMINATE)
//                .setLabel("加载中")
                .setCancellable(false)
                .setAnimationSpeed(2)
                .setDimAmount(0.5f)
                .show()
                : null;

        Map<String, Object> params = new HashMap<>();
        params.put("page", page);
        String categoryId = ClassificationManager.getInstance().getClassificationId();
        switch (categoryId) {
            case ClassificationManager.ID_NO_IMAGE_TAG:
                params.put("imageId", 0);
                break;
            case ClassificationManager.ID_ALL_PRODUCT:
                break;
            default:
                params.put("categoryId", categoryId);
        }

        String extalMode = ClassificationManager.getInstance().getExtralMode();
        switch (extalMode) {
            case ClassificationManager.MODE_EXTRA_KEY_WORD:
                String searchKeyword = ClassificationManager.getInstance().getKeyword();
                if (!TextUtils.isEmpty(searchKeyword)) {
                    params.put("searchWord", searchKeyword);
                }
                break;
            case ClassificationManager.MODE_EXTRA_KEY_LIKE:
                loadLikelyProduct(page, hubDialog, fullyRefresh);
                return;
            case ClassificationManager.MODE_EXTRA_KEY_RECOGNITION:
                loadRecognizeResult(page, null, fullyRefresh);
                return;
            case ClassificationManager.MODE_EXTRA_PARAMS_FILTER:
                loadFilterResult(page, hubDialog, fullyRefresh);
                return;
            default:
                break;
        }

        ParamRequestModel paramRequestModel = getCurrentParamRequestMode();

        Subscription subscription = NetworkManager.getInstance().getRetrofit().create(ProductService.class)
                .listProductInfo(params, paramRequestModel)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(productListWrappers -> {
                    JUtils.Log("load product success.");
                    setData(isRefresh, productListWrappers.getProducts());
                    if (isRefresh) {
                        mSummaryAdapter.notifyDataSetChanged();
                    }
                }, throwable -> {
                    ErrorHandler.handlerNetworError(throwable, "加载失败，请检查网络状态");
                    JUtils.Log("load product error.");
                    throwable.printStackTrace();
                    if (hubDialog != null) {
                        if (hubDialog.isShowing()) {
                            hubDialog.dismiss();
                        }
                    }
                }, () -> {
                    JUtils.Log("product request completed.");
                    if (hubDialog != null) {
                        if (hubDialog.isShowing()) {
                            hubDialog.dismiss();
                        }
                    }
                });
        mCompositeSubscription.add(subscription);
    }

    private void loadMoreData() {
        JUtils.Log("Load more is called.");
        loadDataFromServer(mNextRequestPage, false, false, false);
    }

    private void loadFilterResult(int page, KProgressHUD dialog, boolean fullyRefresh) {
        Map<String, Object> queryMap = new HashMap<>();
        queryMap.put("page", page);
        Map<String, Object> bodyMap = new HashMap<>();
        if (ClassificationManager.getInstance().getLeatestSimalarProductResult() != null) {
            bodyMap.put("ids", ClassificationManager.getInstance().getLeatestSimalarProductResult().getIds());
        }
        if (ClassificationManager.getInstance().hasParamFilterChecked()) {
            bodyMap.put("parameters", getCurrentParamRequestMode().getParameters());
        }

        Subscription subscription = NetworkManager.getInstance().getRetrofit().create(ProductService.class)
                .listProductInfo(queryMap, bodyMap)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(productListWrapper -> {
                    JUtils.Log("load param filter product successfully.");
                    if (page == 1) {
                        mProductRv.scrollToPosition(0);
                    }
                    setData(page == 1, productListWrapper.getProducts());
                }, throwable -> {
                    JUtils.Log("load param filter product error:" + throwable.getMessage());
                    ErrorHandler.handlerNetworError(throwable, "参数查询失败，请检查网络状态");
                    mSummaryAdapter.setEnableLoadMore(true);
                    if (dialog != null) {
                        dialog.dismiss();
                    }
                }, () -> {
                    mSummaryAdapter.setEnableLoadMore(true);
                    if (dialog != null) {
                        dialog.dismiss();
                    }
                });
        mCompositeSubscription.add(subscription);

    }

    private void loadLikelyProduct(int page, KProgressHUD dialog, boolean fullyRefresh) {
        ImageTellProgressDialog tellDialog = ImageTellProgressDialog.getInstance("请耐心等待，系统正在查找相似");
        tellDialog.setCancelable(false);
        if (page == 1 && fullyRefresh) {
            getChildFragmentManager().beginTransaction()
                    .add(tellDialog, "likelyDialog")
                    .commitAllowingStateLoss();
//            tellDialog.show(getChildFragmentManager(), "likelyDialog");
        }
        Map<String, Object> queryMap = new HashMap<>();
        queryMap.put("page", page);
        Subscription subscription = ClassificationManager.getInstance().loadLikelyProductList(page == 1 && fullyRefresh)
                .flatMap(simalarProductResult -> {
                    Map<String, Object> map = new HashMap<>();
                    map.put("ids", simalarProductResult.getIds());
                    if (ClassificationManager.getInstance().hasParamFilterChecked()) {
                        map.put("parameters", getCurrentParamRequestMode().getParameters());
                    }
                    return NetworkManager.getInstance().getRetrofit().create(ProductService.class)
                            .listProductInfo(queryMap, map);
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(productListWrapper -> {
                    JUtils.Log("load simalar product successfully.");
                    if (page == 1) {
                        mProductRv.scrollToPosition(0);
                    }
                    setData(page == 1, productListWrapper.getProducts());
//                    if (tellDialog != null) {
//                        tellDialog.dismiss();
//                    }

                }, throwable -> {
                    JUtils.Log("load simalar product error:" + throwable.getMessage());
                    ErrorHandler.handlerNetworError(throwable, "加载相似商品失败，请检查网络状态");
                    mSummaryAdapter.setEnableLoadMore(true);
                    Fragment prev = getChildFragmentManager().findFragmentByTag("likelyDialog");
                    if (prev != null) {
                        DialogFragment df = (DialogFragment) prev;
                        df.dismissAllowingStateLoss();
                    }
//                    ClassificationManager.getInstance().quitRecognitionMode();
//                    if (tellDialog != null) {
//                        tellDialog.dismiss();
//                    }
                }, () -> {
                    Fragment prev = getChildFragmentManager().findFragmentByTag("likelyDialog");
                    if (prev != null) {
                        DialogFragment df = (DialogFragment) prev;
                        df.dismissAllowingStateLoss();
                    }
//                    if (tellDialog != null) {
//                        tellDialog.dismiss();
//                    }
                });

        mCompositeSubscription.add(subscription);
    }


    private void setData(boolean isRefresh, List<Product> data) {
        for (int i = 0; i < data.size(); i++) {
            Product item = data.get(i);
            if (ProductSummaryManager.getInstance().getCheckedProudctIdList().contains(item.getId())) {
                JUtils.Log("find one in select items." + item.getPNO());
                boolean needNotify = i == data.size() - 1;
                ProductSummaryManager.getInstance().addProductToCheck(item, needNotify);
            }
        }
        if (mSummaryAdapter == null) return;
        JUtils.Log(TAG, "isRefresh : " + isRefresh);
        mNextRequestPage++;
        final int size = data == null ? 0 : data.size();
        JUtils.Log(TAG, "data size is : " + size);
        if (isRefresh) {
            mSummaryAdapter.setNewData(data);
        } else {
            if (size > 0) {
                JUtils.Log(TAG, "add new data to tail.");
                mSummaryAdapter.addData(data);
            }
        }
        if (size < PAGE_SIZE) {
            mSummaryAdapter.loadMoreEnd(isRefresh);
        } else {
            mSummaryAdapter.loadMoreComplete();
        }
        if (isRefresh && size == 0) {
            mEmptyView.setVisibility(View.VISIBLE);
        } else {
            mEmptyView.setVisibility(View.GONE);
        }
    }

    public void addHeader(LocalMediaWrapper localMediaWrapper, boolean isTotalRecognize) {
        mProductRv.smoothScrollToPosition(0);
        mSummaryAdapter.setNewData(null);
        mSummaryAdapter.removeAllHeaderView();
        ImageTellHeader imageTellHeader = new ImageTellHeader(getContext());
        imageTellHeader.bindData(localMediaWrapper);
        mSummaryAdapter.addHeaderView(imageTellHeader);

        ClassificationManager.getInstance().changeToRecognitionMode(localMediaWrapper, isTotalRecognize);
        mNextRequestPage = 1;
        mSummaryAdapter.setNewData(null);

        /*
        ImageTellProgressDialog dialog = new ImageTellProgressDialog();
        if (mNextRequestPage == 1) {
            dialog.setCancelable(false);
            getChildFragmentManager().beginTransaction()
                    .add(dialog, "ImageTellDialog")
                    .commitAllowingStateLoss();
//            dialog.show(getChildFragmentManager(), "ImageTellDialog");
        }
        */
//        loadRecognizeResult(mNextRequestPage, dialog);
    }

    private ParamRequestModel getCurrentParamRequestMode() {
        ParamRequestModel paramRequestModel = new ParamRequestModel();
        if (ClassificationManager.getInstance().hasParamFilterChecked()) {
            Map<Integer, ParameterManager.ParamCheckStatus> paramsStatusMap = ParameterManager.getInstance().getParamsCheckStatus();
            List<ParamRequestModel.ParameterRequest> parameterRequests = new ArrayList<>();
            if (paramsStatusMap.size() != 0) {
                Set<Integer> keys = paramsStatusMap.keySet();
                for (Integer id : keys) {
                    String key = String.valueOf(id);
                    ParameterManager.ParamCheckStatus paramCheckStatus = paramsStatusMap.get(id);
//                    if (paramCheckStatus != null && values.size() != 0) {
                    if (paramCheckStatus != null) {
                        if (paramCheckStatus.getType() == ParameterManager.TYPE_NORMAL || paramCheckStatus.getType() == ParameterManager.TYPE_SELECT) {
                            if (paramCheckStatus.getOptionsCheck() == null || paramCheckStatus.getOptionsCheck().size() == 0) {
                                continue;
                            }
                            ParamRequestModel.ParameterRequest request = new ParamRequestModel.ParameterRequest();
                            request.setId(key);
                            List<String> valueList = new ArrayList<>();
                            valueList.addAll(paramCheckStatus.getOptionsCheck());
                            request.setValue(valueList);
                            parameterRequests.add(request);
                        } else {
                            if (TextUtils.isEmpty(paramCheckStatus.getMax()) && TextUtils.isEmpty(paramCheckStatus.getMin())) {
                                continue;
                            }
                            ParamRequestModel.ParameterRequest request = new ParamRequestModel.ParameterRequest();
                            request.setId(key);
                            Map<String, Object> rangeMap = new HashMap<>();
                            if (paramCheckStatus.getType() == ParameterManager.TYPE_DATE) {
                                String minDate = paramCheckStatus.getMin();
                                if (TextUtils.isEmpty(minDate)) {
                                    rangeMap.put("min", null);
                                } else {
                                    minDate += " 00:00:00";
                                    long startTs = Timestamp.valueOf(minDate).getTime();
                                    rangeMap.put("min", startTs);
                                }
                                String maxDate = paramCheckStatus.getMax();
                                if (TextUtils.isEmpty(maxDate)) {
                                    rangeMap.put("max", null);
                                } else {
                                    maxDate += " 00:00:00";
                                    long endTs = Timestamp.valueOf(maxDate).getTime();
                                    rangeMap.put("max", endTs);
                                }
                            } else {
                                if (!TextUtils.isEmpty(paramCheckStatus.getMax()) ||
                                        !TextUtils.isEmpty(paramCheckStatus.getMin())) {
                                    String maxStr = paramCheckStatus.getMax();
                                    String minStr = paramCheckStatus.getMin();
                                    if (TextUtils.isEmpty(maxStr)) {
                                        rangeMap.put("max", null);
                                    } else {
                                        rangeMap.put("max", Long.parseLong(maxStr));
                                    }
                                    if (TextUtils.isEmpty(minStr)) {
                                        rangeMap.put("min", null);
                                    } else {
                                        rangeMap.put("min", Long.parseLong(minStr));
                                    }
                                } else {
                                    continue;
                                }
                            }
                            request.setRangeMap(rangeMap);
                            request.setValue(null);
                            parameterRequests.add(request);
                        }
                    }
                }
                paramRequestModel.setParameters(parameterRequests);
            }
        }
        return paramRequestModel;
    }

    private void loadRecognizeResult(int page, ImageTellProgressDialog imageTellProgressDialog, boolean fullyRefresh) {
        JUtils.Log(TAG, "loadRecognizeResult called.");

        ImageTellProgressDialog dialog = new ImageTellProgressDialog();
        if (mNextRequestPage == 1 && fullyRefresh) {
            dialog.setCancelable(false);
            getChildFragmentManager().beginTransaction()
                    .add(dialog, "ImageTellDialog")
                    .commitAllowingStateLoss();
//            dialog.show(getChildFragmentManager(), "ImageTellDialog");
        }
        Subscription subscription = ClassificationManager.getInstance().loadRecognizeProductList(page == 1 && fullyRefresh)
                .flatMap(simalarProductResult -> {
                    Map<String, Object> bodymap = new HashMap<>();
                    bodymap.put("ids", simalarProductResult.getIds());
                    JUtils.Log(TAG, "ids size is : " + simalarProductResult.getIds().size());
                    Map<String, Object> innerMap = new HashMap<>();
                    innerMap.put("page", page);
                    bodymap.put("page", page);
                    if (ClassificationManager.getInstance().hasParamFilterChecked()) {
                        bodymap.put("parameters", getCurrentParamRequestMode().getParameters());
                    }
                    return NetworkManager.getInstance().getRetrofit().create(ProductService.class)
                            .listProductInfo(innerMap, bodymap);
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(productWrapper -> {
//                    if (dialog != null) {
//                        dialog.dismiss();
//                    }
                    Fragment prev = getChildFragmentManager().findFragmentByTag("ImageTellDialog");
                    if (prev != null) {
                        DialogFragment df = (DialogFragment) prev;
                        df.dismissAllowingStateLoss();
                    }
                    JUtils.Log("upload image success.");
                    setData(page == 1, productWrapper.getProducts());
                }, throwable -> {
                    Fragment prev = getChildFragmentManager().findFragmentByTag("ImageTellDialog");
                    if (prev != null) {
                        DialogFragment df = (DialogFragment) prev;
                        df.dismissAllowingStateLoss();
                    }
                    ErrorHandler.handlerNetworError(throwable, "识别图片失败，请检查网络状态");
//                    if (dialog != null) {
//                        dialog.dismiss();
//                    }
//                    JUtils.Log("upload image error:" + throwable.getMessage());
//                    throwable.printStackTrace();
                });

        mCompositeSubscription.add(subscription);
    }


    @Override
    public void onDestroyView() {
        JUtils.Log(TAG, "onDestroyView");
        mCompositeSubscription.clear();
        ProductSummaryManager.getInstance().removeProductCheckChangeListener(this);
        ParameterManager.getInstance().removeOnParamsChangeListener(this);
        super.onDestroyView();
    }

    @Override
    public void OnProductCheckChanged(int count) {
        mSummaryAdapter.notifyDataSetChanged();
        mTempFloatView.setCount(count);
    }

    @Override
    public void onParamChanged() {
        refreshData(false, false);
        mSummaryAdapter.notifyDataSetChanged();
    }

    public void removeHeader() {
        if (mSummaryAdapter != null) {
            mSummaryAdapter.removeAllHeaderView();
        }
    }
}
